/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import static DAO.AbstractDAO.fermeturesSilencieuses;
import static DAO.AbstractDAO.initialisationRequetePreparee;
import Modele.Velo;
import Utils.Constantes;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 *
 * @author 20cent
 */
public class VeloDAOmysql extends AbstractDAO implements VeloDao {

    private static final String SQL_INSERT = "INSERT INTO `nemo_velo`.`" + ChampsBDD.TABLE_VELO + "` (`"
            + ChampsBDD.VELO_ID + "`, `"
            + ChampsBDD.VELO_SERIAL
            + "`) VALUES (NULL, ?);";
    private static final String SQL_UPDATE = "UPDATE `nemo_velo`.`" + ChampsBDD.TABLE_VELO + "` SET `"
            + ChampsBDD.STATION_ID + "` = ? "
            + "WHERE `" + ChampsBDD.VELO_ID + "` = ?;";
    private static final String SQL_DELETE = "DELETE FROM `nemo_velo`.`" + ChampsBDD.TABLE_VELO + "` "
            + "WHERE `" + ChampsBDD.VELO_ID + "` = ?;";
    private static final String SQL_SELECT_PAR_ID = "SELECT * "
            + "FROM  `" + ChampsBDD.TABLE_VELO + "` "
            + "WHERE  `" + ChampsBDD.VELO_ID + "` = ?";
    private static final String SQL_SELECT_PAR_SERIAL = "SELECT * "
            + "FROM  `" + ChampsBDD.TABLE_VELO + "` "
            + "WHERE  `" + ChampsBDD.VELO_SERIAL + "` = ?";
    private static final String SQL_SELECT_PAR_STATION = "SELECT * "
            + "FROM  `" + ChampsBDD.TABLE_VELO + "` "
            + "WHERE  `" + ChampsBDD.STATION_ID + "` = ?";
    private static final String SQL_SELECT_ALL = "SELECT * "
            + "FROM  `" + ChampsBDD.TABLE_VELO + "` "
            + "LIMIT ?, "+ Constantes.LIGNE_PAR_PAGE+";";

    public VeloDAOmysql(DAOFactory daoFactory) {
        super(daoFactory);
    }

    @Override
    public void save(Velo velo) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet valeursAutoGenerees = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_INSERT, true, velo.getmSerial());
            int statut = preparedStatement.executeUpdate();
            /* Analyse du statut retourné par la requête d'insertion */
            if (statut == 0) {
                throw new DAOException("Échec de la création du vélo, aucune ligne ajoutée dans la table.");
            }
            /* Récupération de l'id auto-généré par la requête d'insertion */
            valeursAutoGenerees = preparedStatement.getGeneratedKeys();
            if (valeursAutoGenerees.next()) {
                /* Puis initialisation de la propriété id du bean Utilisateur avec sa valeur */
                velo.setMId(valeursAutoGenerees.getInt(1));
            } else {
                throw new DAOException("Échec de la création du vélo en base, aucun ID auto-généré retourné.");
            }
        } catch (SQLException e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(valeursAutoGenerees, preparedStatement, connexion);
        }
    }

    @Override
    public void update(Velo velo, int stationId) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_UPDATE, false, stationId, velo.getMId());
            int statut = preparedStatement.executeUpdate();
            /* Analyse du statut retourné par la requête d'insertion */
            if (statut == 0) {
                throw new DAOException("Échec de la mise à jour du vélo, aucune ligne modifiée dans la table.");
            }

        } catch (SQLException e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(preparedStatement, connexion);
        }
    }

    @Override
    public void delete(Velo velo) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_DELETE, false, velo.getMId());
            int statut = preparedStatement.executeUpdate();
            /* Analyse du statut retourné par la requête d'insertion */
            if (statut == 0) {
                throw new DAOException("Échec de la suppression du vélo, aucune ligne supprimée dans la table.");
            }

        } catch (SQLException e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(preparedStatement, connexion);
        }
    }

    @Override
    public Velo getByID(int id) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Velo velo = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_SELECT_PAR_ID, false, id);
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            if (resultSet.next()) {
                velo = map(resultSet);
            }
        } catch (Exception e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(resultSet, preparedStatement, connexion);
        }
        return velo;
    }

    @Override
    public Velo getBySerial(int serial) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Velo velo = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_SELECT_PAR_SERIAL, false, serial);
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            if (resultSet.next()) {
                velo = map(resultSet);
            }
        } catch (Exception e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(resultSet, preparedStatement, connexion);
        }
        return velo;
    }

    
    @Override
    public ArrayList<Velo> getByStation(int stationId) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        ArrayList<Velo> liste = new ArrayList<>();

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_SELECT_PAR_STATION, false, stationId);
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            while (resultSet.next()) {
                liste.add(map(resultSet));
            }
        } catch (Exception e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(resultSet, preparedStatement, connexion);
        }
        return liste;
    }

    @Override
    public ArrayList<Velo> getAll(int page) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        ArrayList<Velo> liste = new ArrayList<>();

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_SELECT_ALL, false, (page-1)*Constantes.LIGNE_PAR_PAGE);
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            while (resultSet.next()) {
                liste.add(map(resultSet));
            }
        } catch (Exception e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(resultSet, preparedStatement, connexion);
        }
        return liste;
    }

    public static Velo map(ResultSet resultSet) throws SQLException {
        Velo velo = new Velo();

        velo.setMId(resultSet.getInt(ChampsBDD.VELO_ID));
        velo.setMDateEntree(resultSet.getDate(ChampsBDD.VELO_DATE_ENTREE));
        velo.setmSerial(resultSet.getInt(ChampsBDD.VELO_SERIAL));

        return velo;
    }
}
